﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using DAL;
using Models;
using WebShopAPI.Models;//前端models命名空间，用来定义类
namespace WebShopAPI.Controllers
{
    //[RoutePrefix("api")]
    /// <summary>
    ///  类别相关操作  
    /// </summary>
    public class categoriesController : ApiController
    {
        sp_categoryService capeServcie = new sp_categoryService();//数据提供类对象
        sp_attributeDAL spattributeService = new sp_attributeDAL();//类型参数数据服务类

        #region 1 商品分类数据列表
        /// <summary>
        /// 商品分类数据列表
        /// </summary>
        /// <param name="type">1，2，3 分别表示显示一层二层三层分类列表<br />【可选参数】如果不传递，则默认获取所有级别的分类</param>
        /// <param name="pagenum">当前页码</param>
        /// <param name="pagesize">每页条件</param>
        /// <returns>级别数据json格式</returns>
        public ResponData Get(int type = 3, int pagenum = 1, int pagesize = 100)
        {
            List<sp_category> cateAll = capeServcie.GetAll();
            //查询级别数据
            cateAll = cateAll.Where(p => p.cat_level <= (type - 1)).ToList();
            //////////////////////
            List<sp_category> firstPer = cateAll.Where(p => p.cat_level == 0).ToList();
            //一级的父级为0
            //创建要返回的数据集合，并进行处理
            List<CateItem> allmenu = new List<CateItem>();
            //通过一级循环
            foreach (var obj in firstPer)
            {
                //读取所有一级构建成对象
                CateItem menu = new CateItem()
                {
                    cat_id = obj.cat_id,
                    cat_name = obj.cat_name,
                    cat_level = obj.cat_level,
                    cat_pid = 0
                };
                if (type == 3)
                {
                    //读取该一级数据的二级
                    var secondePer = cateAll.Where(p => p.cat_pid == obj.cat_id).Select(
                        p => new CateItem
                        {
                            //二级对象构建
                            cat_id = p.cat_id,
                            cat_name = p.cat_name,
                            cat_level = p.cat_level,
                            cat_pid = obj.cat_id,
                            children = cateAll.Where(p3 => p3.cat_pid == p.cat_id).Select(p4 =>
                            new CateItem
                            {
                                cat_id = p4.cat_id,
                                cat_name = p4.cat_name,
                                cat_level = p4.cat_level,
                                cat_pid = p.cat_id

                            }).ToList()
                        }
                        );
                    //修改一级的二级菜单集合
                    menu.children = secondePer.ToList();
                    ///////////////////////////////////////
                    allmenu.Add(menu);//加入到所有菜单集合中  
                }
                else if (type == 2)
                {
                    //读取该一级数据的二级
                    var secondePer = cateAll.Where(p => p.cat_pid == obj.cat_id).Select(
                        p => new CateItem
                        {
                            //二级对象构建
                            cat_id = p.cat_id,
                            cat_name = p.cat_name,
                            cat_level = p.cat_level,
                            cat_pid = obj.cat_id,
                        }
                        );
                    //修改一级的二级菜单集合
                    menu.children = secondePer.ToList();
                    ///////////////////////////////////////
                    allmenu.Add(menu);//加入到所有菜单集合中  
                }


            }
            ///////=====//////////////
            int total = allmenu.Count;//总记录数
            if (type == 3)
            {
                int skipNum = (pagenum - 1) * pagesize;//当前页码-1 

                allmenu = allmenu.Skip(skipNum).Take(pagesize).ToList();//分页提取数据 
            }

            ResponData rd = new ResponData();
            rd.data = new
            {
                totalpage = total,
                pagenum = pagesize,
                catelist = allmenu
            };
            rd.meta.msg = "获取成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion

        #region 2 添加分类
        public ResponData Post(AddCateRequest robj)
        {
            sp_category spcate = new sp_category();
            spcate.cat_name = robj.cat_name;
            spcate.cat_pid = robj.cat_pid;
            spcate.cat_level = robj.cat_level;
            spcate.cat_deleted = 0;
            //调用增加
            capeServcie.Add(spcate);
            // 转成要响应对象
            CateRespone cpobj = new CateRespone();
            cpobj.cate_id = spcate.cat_id;
            cpobj.cat_name = spcate.cat_name;
            cpobj.cat_pid = spcate.cat_pid + "";
            cpobj.cat_level = spcate.cat_level + "";
            //////////////////////////
            ResponData rd = new ResponData();
            rd.data = cpobj;
            rd.meta.msg = "获取成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion

        #region 3 根据id查询分类
        public ResponData Get(int id)
        {
            /////////////////////
            sp_category spcate = capeServcie.GetOne(id);
            CateRespone cr = new CateRespone()
            {
                cate_id = spcate.cat_id,
                cat_name = spcate.cat_name,
                cat_pid = spcate.cat_pid + "",
                cat_level = spcate.cat_level + ""
            };
            ////////////////////
            ResponData rd = new ResponData();
            rd.data = cr;
            rd.meta.msg = "获取成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion

        #region 4 编辑提交分类
        public ResponData Put(int id, [FromBody] string cat_name)
        {
            sp_category spcate = capeServcie.GetOne(id);
            spcate.cat_name = cat_name;
            //调用
            capeServcie.Modify(spcate);
            ////////////////////////
            CateRespone cr = new CateRespone()
            {
                cate_id = spcate.cat_id,
                cat_name = spcate.cat_name,
                cat_pid = spcate.cat_pid + "",
                cat_level = spcate.cat_level + ""
            };
            ResponData rd = new ResponData();
            rd.data = cr;
            rd.meta.msg = "更新成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion

        #region 5 删除分类
        public ResponData Delete(int id)
        {
            //
            capeServcie.DeleteOne(id);
            //
            ResponData rd = new ResponData();
            rd.data = null;
            rd.meta.msg = "删除成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion

        ////////////////////////分类参数管理
        #region 1.7.1 类型下参数列表  方法名有几个get C#多态区分,请求过来不好区分路由，可以自已配置 也可能加一个web api类，让前端调用别外
        [Route("api/categories/{id}/attributes")]
        public ResponData Get(int id, string sel)
        {

            //查询所有参数信息
            List<sp_attribute> attrAll = spattributeService.GetAll();
            //按条件筛选
            var list = attrAll.Where(
                p => p.cat_id == id
                &&
                p.attr_sel.ToUpper().Trim() == sel.ToUpper().Trim()
                &&
                !p.delete_time.HasValue  //删除就有时间，有时间说明是删除的列
                );
            /////////////////////
            ResponData rd = new ResponData();
            rd.data = list;
            rd.meta.msg = "获取成功";
            rd.meta.status = 200;
            return rd;

        }
        #endregion

        #region 1.7.2 添加动态参数或者静态属性 post请求要用对象接收数据 

        [Route("api/categories/{id}/attributes")]
        public ResponData post(int id, AddAttrible addobj)
        {
            //////////////////////////////
            sp_attribute att = new sp_attribute();//数据库对应
            att.attr_name = addobj.attr_name;//接受的名
            att.attr_sel = addobj.attr_sel;
            att.attr_vals = addobj.attr_vals;
            //其他末接收的，可以来源其他地方，也可以是默认值
            att.cat_id = id;//所属类别
            att.attr_write = addobj.attr_sel == "only" ? "manual" : "list";
            //调用持久化
            spattributeService.Add(att);
            ////////////////////////////
            ResponData rd = new ResponData();
            rd.data = att;//新增对象返回，正常模式这里也要处理成一个新对象
            rd.meta.msg = "创建成功";
            rd.meta.status = 200;

            return rd;
        }
        #endregion

        #region 1.7.3  删除参数
        [Route("api/categories/{id}/attributes/{attrid}")]
        public ResponData delete(int id, int attrid)
        {
            //////////删除用逻辑删除，改一列的值 可以在数据服务层加一个按catid=3 and attrid=111/////////////
            var spobj = spattributeService.GetOne(attrid);
            //修改时间
            spobj.delete_time = (DateTime.Now - new DateTime(1900, 1, 1)).Milliseconds;
            //
            spattributeService.Modify(spobj);
            ///////////////////////////////////////////////
            ResponData rd = new ResponData();
            rd.data = null;
            rd.meta.msg = "删除成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion

        #region 1.7.4 根据id查询参数
        [Route("api/categories/{id}/attributes/{attrId}")]
        public ResponData Get(int id, int attrId, string attr_sel = "", string attr_vals = "")
        {
            ///////////////////////
            var obj = spattributeService.GetOne(attrId);
            //其他参数好象现在没有有,....
            ///////响应数据////////////////
            ResponData rd = new ResponData();
            rd.data = obj;
            rd.meta.msg = "获取成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion

        #region 1.7.5. 编辑提交参数
        [Route("api/categories/{id}/attributes/{attrId}")]
        public ResponData Put(int id, int attrId, AddAttrible addobj) //如修改不一样，也需要定义接收修改相应类
        {
            ///////////////////////////////
            sp_attribute att = spattributeService.GetOne(attrId);//数据库对应
            att.attr_name = addobj.attr_name;//接受的名
            att.attr_sel = addobj.attr_sel;
            if (!string.IsNullOrEmpty(addobj.attr_vals)) //说明传值过来了,要改，末传值不用改
            {
                att.attr_vals = addobj.attr_vals;
            }

            //调用修改
            spattributeService.Modify(att);
            //////////////////////////////
            ResponData rd = new ResponData();
            rd.data = att;
            rd.meta.msg = "修改成功";
            rd.meta.status = 200;
            return rd;
        }
        #endregion
    }
    //添加接收类
    public class AddCateRequest
    {
        public int cat_pid { get; set; }
        public string cat_name { get; set; }

        public int cat_level { get; set; }
    }

    public class CateRespone
    {
        public int cate_id { get; set; }
        public string cat_name { get; set; }

        public string cat_pid { get; set; }

        public string cat_level { get; set; }
    }

    //1.7.2  添加动态参数 post 方法对应后台接收数据类,其实可以参数数据库对应，但是这样会暴露后台数据结构,一般会多加一个
    //接受数据的类，响应数据的类
    public class AddAttrible
    {
        public string attr_name { get; set; }
        public string attr_sel { get; set; }

        public string attr_vals { get; set; }
    }
}